home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * Nondeterministic Systems Computer Simulation 2
- *
- * Exponential Distribution
- *
- * This program simulates an exponential distribution. It generates a number by the
- * equation y = -ln(x), where x is a random number greater than 0 and less than or
- * equal to 1 (since ln(0) is not defined). The program also generates the theoretical
- * frequency by obtaining the theoretical probability between two points and multiplying
- * by the number of samples. From the frequency, the distribution function can be
- * obtained by summing the frequencies from 0 to the current point and dividing by the
- * total number of samples taken.
- *
- * Develop a program that performs the function y = -ln(x) where x is a random
- * real number between 0 and 1 (but it cannot equal 0, although 1 is allowed).
- * Keep track of the number of times a value y falls between an arbitrary interval
- * (which you decide upon). This is the probability that the random variable y
- * falls within the interval. The distribution function is the probability that
- * y <= a specified value. This can be accomplished by summing all densities
- * (what was calculated previously) from the beginning up to the current y.
- *
- * The random variable y should be calculated thousands of times and the table
- * of distributions should be printed to a file.
- *
- */
-
-
- /* ------------------------------------------------------------------------------- */
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <time.h>
-
-
- /* ------------------------------------------------------------------------------- */
-
-
- #define MAX_ITERATIONS 500000L /* number of samples generated */
- #define MAX_INTERVALS 100 /* maximum number of samples intervals */
- #define DISCRETE 10.0 /* number of discrete samples for an interval of 1:
- 10 samples between 0 and 1, another 10 between
- 1 and 2, etc. */
- #define ONE_TENTH 0 /* indexes for probability array */
- #define ONE_HALF 1
- #define ONE 2
- #define TWO 3
-
-
- /* ------------------------------------------------------------------------------- */
-
-
- main()
- {
- long i; /* loop counter */
- long count; /* variables to sum the frequencies */
- long count2;
- double y; /* random variable */
- double divisor = RAND_MAX + 1.0; /* used to divide random number; done as variable
- to save addition and double conversion time */
- long density[MAX_INTERVALS]; /* array stores sampled density */
- long probability[TWO+1]; /* array to store probability frequencies */
- long theoretical[MAX_INTERVALS]; /* array to store theoretical sampling */
- double p_theoretical[TWO+1]; /* array of theoretical probabilities */
- FILE *fp; /* file control block pointer */
-
- srand(time(NULL)); /* seeds the random number generator */
-
- /*
- Clear arrays that will be incremented.
- */
-
- for (i=0L; i<(long) MAX_INTERVALS; i++)
- density[i] = 0;
- for (i=0L; i<(TWO + 1L); i++)
- probability[i] = 0;
-
- /*
- For comparison, the theoretical probability is generated below. This probability
- is applied to an interval by multiplying it with the maximum iterations, thus a
- number of theoretical samples are created to compare with the simulation.
- */
-
- for (i=0L; i<(long) MAX_INTERVALS; i++)
- {
- y = -( exp( -(i+1)/DISCRETE ) - exp( -i/DISCRETE ) );
- theoretical[i] = (long) floor(y * MAX_ITERATIONS + 0.5);
- }
- p_theoretical[ONE_TENTH] = -( exp( -0.1 ) - exp( 0.0 ) );
- p_theoretical[ONE_HALF] = -( exp( -0.5 ) - exp( 0.0 ) );
- p_theoretical[ONE] = -( exp( -1.0 ) - exp( 0.0 ) );
- p_theoretical[TWO] = -( exp( -2.0 ) - exp( 0.0 ) );
-
- /*
- The code below does the actual simulation. A random number is generated by use
- of rand() between 0 and RAND_MAX (2^31 - 1). This number must be converted to
- to a number varying between 0 and 1 (but cannot equal 0). Thus, rand() is divided
- by (RAND_MAX + 1) and subtracted from 1. If the value is less than certain
- numbers, their probability is incremented.
- */
-
- for (i=0L; i<MAX_ITERATIONS; i++)
- {
- y = -log(1.0 - ((double) rand() / divisor));
- if (y <= 0.1)
- probability[ONE_TENTH]++;
- if (y <= 0.5)
- probability[ONE_HALF]++;
- if (y <= 1.0)
- probability[ONE]++;
- if (y <= 2.0)
- probability[TWO]++;
-
- /*
- Now, the random variable is multiplied by DISCRETE. This allows for sampling. A
- sample is taken DISCRETE times between two successive integers (such as 0 and 1 or
- 1 and 2, etc.). If the random variable is within the sample range (less than
- MAX_INTERVALS), the density is incremented. The sampling needs to be done
- since the function provided is continuous, but a this computer simulation only deals
- with discrete numbers.
- */
-
- y *= DISCRETE;
- if ( ((int) y) < MAX_INTERVALS )
- density[(int) y]++;
- }
-
- /*
- The data is then output to a file. Three output files are created. Two will just
- contain the raw data with no labels. This data will be copied and placed into Excel.
- The other data is labeled so that reading is quite easy. This file is included
- with the report.
- */
-
- fp = fopen("Sim density.dat", "w"); /* raw data for simulation density */
- for (i=0; i<(long) MAX_INTERVALS; i++)
- fprintf(fp, "%ld\n", density[i]);
- fclose(fp);
-
- fp = fopen("Theor density.dat", "w"); /* raw data for theoretical density */
- for (i=0; i<(long) MAX_INTERVALS; i++)
- fprintf(fp, "%ld\n", theoretical[i]);
- fclose(fp);
-
- count = 0L;
- fp = fopen("Sim distribution.dat", "w"); /* raw data for simulation distribution */
- for (i=0; i<(long) MAX_INTERVALS; i++)
- {
- count += density[i];
- fprintf(fp, "%lf\n", (double) count / (double) MAX_ITERATIONS);
- }
- fclose(fp);
-
- count = 0L;
- fp = fopen("Theor distribution.dat", "w"); ./* raw data for theoretical distribution */
- for (i=0; i<(long) MAX_INTERVALS; i++)
- {
- count += theoretical[i];
- fprintf(fp, "%lf\n", (double) count / (double) MAX_ITERATIONS);
- }
- fclose(fp);
-
- fp = fopen("Exponential.out", "w");
- fprintf(fp, "Minimum Value Maximum Value Samples Theor Samples");
- fprintf(fp, " Distribution Theor Distribution\n");
- count = 0L;
- count2 = 0L;
- for (i=0; i<(long) MAX_INTERVALS; i++)
- {
- count += density[i];
- count2 += theoretical[i];
- fprintf(fp, "%8.1lf %16.1lf %12ld %12ld %16.6lf %17.6lf\n", i/DISCRETE,
- (i+1)/DISCRETE, density[i], theoretical[i], (double) count /
- (double) MAX_ITERATIONS, (double) count2 / (double) MAX_ITERATIONS);
- }
- fprintf(fp, "\n\nP(y<=0.1) = %lf P(theoretical)(y<=0.1) = %lf\n",
- (double) probability[ONE_TENTH]/(double) MAX_ITERATIONS, p_theoretical[ONE_TENTH]);
- fprintf(fp, "P(y<=0.5) = %lf P(theoretical)(y<=0.5) = %lf\n",
- (double) probability[ONE_HALF]/(double) MAX_ITERATIONS, p_theoretical[ONE_HALF]);
- fprintf(fp, "P(y<=1.0) = %lf P(theoretical)(y<=1.0) = %lf\n",
- (double) probability[ONE]/(double) MAX_ITERATIONS, p_theoretical[ONE]);
- fprintf(fp, "P(y<=2.0) = %lf P(theoretical)(y<=2.0) = %lf\n",
- (double) probability[TWO]/(double) MAX_ITERATIONS, p_theoretical[TWO]);
- fclose(fp);
- }
-